import fs from 'fs';
import path from 'path';
import type { Logger } from './logger';
import type { RollupWarning, WarningHandler } from 'rollup';
import chalk from 'chalk';

export function slash(p: string): string {
  return p.replace(/\\/g, '/');
}

export function writeFile(filename: string, content: string | Uint8Array): void {
  const dir = path.dirname(filename);
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
  }
  fs.writeFileSync(filename, content);
}

export function emptyDir(dir: string): void {
  if (!fs.existsSync(dir)) {
    return;
  }
  // eslint-disable-next-line no-restricted-syntax
  for (const file of fs.readdirSync(dir)) {
    const abs = path.resolve(dir, file);
    // baseline is Node 12 so can't use rmSync :(
    if (fs.lstatSync(abs).isDirectory()) {
      emptyDir(abs);
      fs.rmdirSync(abs);
    } else {
      fs.unlinkSync(abs);
    }
  }
}

export function copyDir(srcDir: string, destDir: string): void {
  fs.mkdirSync(destDir, { recursive: true });
  // eslint-disable-next-line no-restricted-syntax
  for (const file of fs.readdirSync(srcDir)) {
    const srcFile = path.resolve(srcDir, file);
    const destFile = path.resolve(destDir, file);
    const stat = fs.statSync(srcFile);
    if (stat.isDirectory()) {
      copyDir(srcFile, destFile);
    } else {
      fs.copyFileSync(srcFile, destFile);
    }
  }
}

const warningIgnoreList = [`CIRCULAR_DEPENDENCY`, `THIS_IS_UNDEFINED`];
const dynamicImportWarningIgnoreList = [`Unsupported expression`, `statically analyzed`];

export function onRollupWarning(
  logger: Logger,
  warning: RollupWarning,
  warn: WarningHandler,
): void {
  if (warning.code === 'UNRESOLVED_IMPORT') {
    const id = warning.source;
    const { importer } = warning;
    if (!importer || !/\?commonjs-external$/.test(importer)) {
      throw new Error(`[seepfly]: rollup 无法解析从 "${importer}" 中引入 "${id}"`);
    }
  }

  if (
    warning.plugin === 'rollup-plugin-dynamic-import-variables' &&
    dynamicImportWarningIgnoreList.some((msg) => warning.message.includes(msg))
  ) {
    return;
  }

  if (!warningIgnoreList.includes(warning.code!)) {
    if (warning.code === 'PLUGIN_WARNING') {
      logger.warn(
        `${chalk.bold.yellow(`[plugin:${warning.plugin}]`)} ${chalk.yellow(warning.message)}`,
      );
    } else {
      warn(warning);
    }
  }
}
